package com.xxx.springboot;

import com.alibaba.csp.sentinel.init.InitExecutor;
import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation;
import com.alicp.jetcache.anno.config.EnableMethodCache;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import com.xxx.springboot.bean.User;
import com.xxx.springboot.filter.MdcFilter;
import com.xxx.springboot.listener.SystemListener;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * spring boot 程序启动入口
 */
@SpringBootApplication
@EnableMethodCache(basePackages="com.xxx.springboot")	// jetcache
@EnableCreateCacheAnnotation
@EnableRedisHttpSession(redisNamespace = "et:session") // redis 分布式session
@MapperScan("com.xxx.springboot.mapper")
@EnableTransactionManagement // 开启spring事务
@EnableAsync  	// 开启异步任务，使@Async注解生效
@EnableCaching  // 开启缓存
@EnableApolloConfig  //  开启apollo配置
@EnableRetry	// 开启@Retryable重试框架
@ServletComponentScan(basePackageClasses = {MdcFilter.class})  // 2.开启MDC日志链路追踪过滤器
public class Application {

	public static void main(String[] args) {
		SpringApplication springApplication = new SpringApplication(Application.class);
        springApplication.addListeners(new SystemListener()); // 添加listener
        ApplicationContext context = springApplication.run(args);
        triggerSentinelInit(); // Sentinel限流初始化

		User user = (User) context.getBean("user");
		System.out.println(user.toString());

		System.out.println("Shutdown application context");
	}

	private static void triggerSentinelInit() {
		new Thread(() -> InitExecutor.doInit()).start();
	}

	@Bean(name = "user", initMethod = "doInit", destroyMethod = "doDestroy")
	public User create() {
		User user = new User();
		user.setName("guwq");
		user.setAge(28);
		return user;
	}

}
